#define WIN32_LEAN_AND_MEAN
#include "windows.h"
#include "common.h"
#include "vectormath.h"
#include <Commdlg.h>
#include "math.h"

// ===========================================================
// Config data
// ===========================================================

bool Config::exitApp = false;


namespace Tmpl {

// ===========================================================
// Lerp
// ===========================================================

float Lerp(float start, float end, float pct)	
{
	return (start + (end - start) * pct);
}

double Lerp(double start, double end, double pct)	
{
	return (start + (end - start) * pct);
}

Vec2f Lerp(Vec2f start, Vec2f end, float pct)	
{
	return (start + (end - start) * pct);
}

Vec3f Lerp(Vec3f start, Vec3f end, float pct)	
{
	return (start + (end - start) * pct);
}

Quaternionf Lerp(Quaternionf start, Quaternionf end, float pct)	
{
	return (start + (end - start) * pct);
}

Orientationf Lerp(Orientationf start, Orientationf end, float pct)	
{
	return Orientationf(Lerp(start.pos, end.pos, pct), Slerp(start.rot, end.rot, pct));
}


// ===========================================================
// Timer class implementation
// ===========================================================

Timer::Timer() : mRunning(false), mStartT(0), mStopT(0)
{
}

double Timer::GetElapsedDp()
{
	if(mRunning) mStopT = WinGetSystemTime();
	return (mStopT - mStartT);
}

float Timer::GetElapsed()
{
	if(mRunning) mStopT = WinGetSystemTime();
	return (float)(mStopT - mStartT);
}

void Timer::Reset()
{
	mStartT = mStopT = 0.0;
	mRunning = false;
}

void Timer::Start()
{
	mStartT = WinGetSystemTime();
	mRunning = true;
}

void Timer::Stop()
{
	mStopT = WinGetSystemTime();
	mRunning = false;
}

bool WinFileDialog(char* buffer, int bufferSize, const char* extensions)
{
	char cwd[1024];
	GetCurrentDirectory(1024, cwd);

	OPENFILENAME ofn;
	ZeroMemory(&ofn, sizeof(ofn));
	ofn.lStructSize = sizeof(ofn);
	ofn.hwndOwner = NULL;
	ofn.lpstrFile = buffer;
	ofn.lpstrFile[0] = '\0';
	ofn.nMaxFile = bufferSize;
	ofn.lpstrFilter = (extensions ? extensions : "All (*.*)\0*.*\0");
	ofn.nFilterIndex = 1;
	ofn.lpstrFileTitle = NULL;
	ofn.nMaxFileTitle = 0;
	ofn.lpstrInitialDir = NULL;
	ofn.Flags = OFN_PATHMUSTEXIST | OFN_FILEMUSTEXIST;
	bool success = GetOpenFileName(&ofn) != 0;
	
	SetCurrentDirectory(cwd);
	return success;
}

bool WinQuestionDialog(const char* caption, const char* question)
{
	int answer = MessageBox(NULL, question, caption, MB_ICONQUESTION | MB_YESNO);
	return (answer == IDYES);
}

void WinMsgDialog(const char* caption, const char* message)
{
	MessageBox(NULL, message, caption, MB_OK);
}

void WinSleep(int milliSeconds)
{
	::Sleep(milliSeconds);
}

double WinGetSystemTime()
{
	static LARGE_INTEGER frequency = {0};
	static BOOL usePerformanceQuery = true;
	
	if(usePerformanceQuery && frequency.QuadPart == 0)
	{
		usePerformanceQuery = QueryPerformanceFrequency(&frequency);
	}
	if(usePerformanceQuery)
	{
		LARGE_INTEGER currentTime;
		QueryPerformanceCounter(&currentTime);
		return (double)currentTime.QuadPart / (double)frequency.QuadPart;
	}
	return (0.001 * (double)GetTickCount());
}

}; // namespace Tmpl